﻿
// **************************************************************************
//    Class Created by Mick Doherty (Dotnetrix) June 2010
//    http://dotnetrix.co.uk/
//
//    ...for GlassUI (an AeroGlass UI Library)
//    http://glassui.codeplex.com/
// **************************************************************************

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;
using GlassUI.Design;

namespace GlassUI
{
    [Designer(typeof(StackedPanelDesigner))]
    [Docking(DockingBehavior.Never)]
    [ToolboxItem(false)]
    public class StackedPanel : HeaderPanel
    {
        #region Private Instance Variables

        private Color headerBackColor = SystemColors.ActiveCaption;

        private static Color defaultGlowColor = SystemColors.Highlight;
        private static Color ambientGlowColor = Color.Empty;
        private Color glowColor = ambientGlowColor;

        private int imageIndex = -1;
        private string imageKey = "";

        private ControlState headerState = ControlState.Normal;

        #endregion

        #region Properties

        internal int CollapsedHeight
        {
            get { return this.HeaderFont.Height + 12; }
        }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override ImageList ImageList
        {
            get 
            {
                StackedPanelControl owner = this.Parent as StackedPanelControl;
                if (owner != null)
                    return owner.ImageList;
                return base.ImageList; 
            }
            set
            {
                StackedPanelControl owner = this.Parent as StackedPanelControl;
                if (owner != null)
                {
                    owner.ImageList = value;
                    this.UpdateNonClient();
                }
            }
        }
        protected new bool ShouldSerializeImageList()
        {
            return false;
        }

        [Category("Appearance"), DefaultValue(-1)]
        [Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design", typeof(UITypeEditor))]
        [GlassUIDescription("ButtonImageIndexDescr", "System.Windows.Forms")]
        [TypeConverter(typeof(ImageIndexConverter))]
        public new int ImageIndex
        {
            get
            {
                if (ImageList == null)
                    return -1;
                if (ImageList.Images.Count < imageIndex)
                    return -1;
                return imageIndex;
            }
            set
            {
                imageIndex = value;
                if (imageKey.Length > 0)
                    imageKey = "";
                if (this.AutoSize)
                    this.OnSizeChanged(EventArgs.Empty);
                this.UpdateNonClient();
            }
        }

        [DefaultValue("")]
        [Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design", typeof(UITypeEditor))]
        [GlassUIDescription("ButtonImageIndexDescr", "System.Windows.Forms")]
        [RefreshProperties(RefreshProperties.All)]
        [TypeConverter(typeof(ImageKeyConverter))]
        public new string ImageKey
        {
            get
            {
                if (ImageList == null)
                    return "";
                if (!ImageList.Images.ContainsKey(imageKey))
                    return "";
                return imageKey;
            }
            set
            {
                imageKey = value;
                if (imageIndex != -1)
                    imageIndex = -1;
                if (this.AutoSize)
                    this.OnSizeChanged(EventArgs.Empty);
                this.UpdateNonClient();
            }
        }

        [DefaultValue(typeof(Color), "ActiveCaption")]
        [GlassUIDescription("HeaderBackColorDescription")]
        public new Color HeaderBackColor
        {
            get
            {
                return headerBackColor;
            }
            set
            {
                if (headerBackColor != value)
                {
                    headerBackColor = value;
                    this.UpdateNonClient();
                }
            }
        }

        [Category("Appearance")]
        [AmbientValue(typeof(Color), "Empty")]
        [GlassUIDescription("GlowColorDescription")]
        public Color GlowColor
        {
            get
            {
                if (this.glowColor == Color.Empty && this.Parent != null)
                {
                    Color color = ReflectedGlowColor(this.Parent);
                    if (!color.IsEmpty)
                        return color;
                    return StackedPanel.defaultGlowColor;
                }
                return this.glowColor;
            }
            set { glowColor = value; }
        }
        
        public void ResetGlowColor()
        {
            this.GlowColor = StackedPanel.ambientGlowColor;
        }

        private bool ShouldSerializeGlowColor()
        {
            return (this.glowColor != StackedPanel.ambientGlowColor);
        }

        internal ControlState HeaderState
        {
            get { return headerState; }
            set 
            {
                if (headerState != value)
                {
                    headerState = value;
                    this.UpdateNonClient();
                }
            }
        }

        #endregion

        #region Overridden Methods

        protected override void OnNonClientClick(System.EventArgs e)
        {
            StackedPanelControl owner = this.Parent as StackedPanelControl;
            if (owner != null)
            {
                owner.SelectedIndex = owner.Controls.IndexOf(this);
                owner.Select();
            }
        }

        protected override void OnNonClientMouseEnter(EventArgs e)
        {
            base.OnNonClientMouseEnter(e);
            if (MouseInHeader() && !this.DesignMode)
                this.HeaderState = ControlState.Hot;
        }

        protected override void OnNonClientMouseMove(MouseEventArgs e)
        {
            base.OnNonClientMouseMove(e);
            this.HeaderState = MouseInHeader() && !this.DesignMode ? ControlState.Hot : ControlState.Normal;
        }

        protected override void OnNonClientMouseLeave(EventArgs e)
        {
            base.OnNonClientMouseLeave(e);
            this.HeaderState = ControlState.Normal;
        }
        
        #endregion

        #region internal methods

        internal static Color ReflectedGlowColor(Control parent)
        {
            PropertyInfo info = parent.GetType().GetProperty("GlowColor");
            if (info != null)
                return (Color)info.GetValue(parent, null);
            GlassForm form = parent.FindForm() as GlassForm;
            if (form != null)
                return form.GlowColor;
            return Color.Empty;
        }

        internal override void DrawHeader(Graphics graphics, Rectangle bounds)
        {
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.CompositingQuality = CompositingQuality.HighQuality;

            GlassForm form = this.FindForm() as GlassForm;

            bool glassify = form == null ? false : form.ControlIsOnGlass(this.Parent);

            Rectangle rc = bounds;
            rc.Width--;
            rc.Height--;

            using (GraphicsPath path = GlassUtilities.RoundedRectangle(bounds, 2))
            {
                graphics.SetClip(path, CombineMode.Replace);
                GlassUtilities.DrawGlowGradient(graphics, bounds, glassify ? Color.FromArgb(128, this.HeaderBackColor) : this.HeaderBackColor, this.GlowColor, this.HeaderState);
                graphics.ResetClip();
                GlassUtilities.DrawRoundedBorder(graphics, bounds, 2, Corners.All, Color.Empty);
            }                    


            bounds.Inflate(-4, 0);
            bounds.Width -= 4;

            Image img = this.Image;

            if (this.ImageList != null)
            {
                if (this.ImageIndex != -1)
                    if (this.ImageList.Images.Count > this.ImageIndex)
                        img = this.ImageList.Images[this.ImageIndex];
                if (this.ImageKey.Length > 0)
                    img = this.ImageList.Images[ImageKey];
            }

            GlassUtilities.RenderStandardContent(graphics, bounds, this.Text, this.HeaderFont, img, ContentAlignment.MiddleCenter, ContentAlignment.MiddleLeft, TextImageRelation.ImageBeforeText, this.HeaderForeColor, false, 8, this.Enabled, TextFormatFlags.EndEllipsis);

            StackedPanelControl owner = this.Parent as StackedPanelControl;
            if (owner != null)
            {
                rc.Inflate(-1, -1);
                if (owner.Focused && this.ShowFocusCues && owner.TabStop && owner.StackedPanels[owner.SelectedIndex] == this)
                    ControlPaint.DrawFocusRectangle(graphics, rc, this.ForeColor, this.BackColor);
            }

        }

        internal bool MouseInHeader()
        {
            Rectangle bounds = new Rectangle(0, 0, this.Width, this.CollapsedHeight);
            return bounds.Contains(this.PointToControl(Cursor.Position));
        }
        
       #endregion

    }
}
